﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using DBUtility;
using System.Text;
using Model;

namespace DAL
{
    public class BaseRepository<T> where T : class
    {
        #region 公共方法
        public void Insert(T Entity,string userID)
        {
            InsertOrUpdate(Entity, GetInsertsp());
            InsertDML(Entity, userID, GetInsertsp());
        }

        public void Update(T Entity, string userID)
        {
            InsertOrUpdate(Entity, GetUpdatesp());
            InsertDML(Entity, userID, GetUpdatesp());
        }

        protected void InsertOrUpdate(T Entity, string sp_name)
        {
            SqlParameter[] Parms = GetParameters();
            SetParameters(Entity, Parms);
            SqlCommand cmd = new SqlCommand();
            foreach (SqlParameter parm in Parms)
                cmd.Parameters.Add(parm);
            ExecuteCommand(cmd, sp_name);
        }

        protected void ExecuteCommand(SqlCommand cmd, string sp_name)
        {
            using (SqlConnection conn = new SqlConnection(sqlHelper.ConnectionStringLocalTransaction))
            {
                conn.Open();
                cmd.Connection = conn;
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = sp_name;
                using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { }
            }
            //using (SqlConnection conn = new SqlConnection(sqlHelper.ConnectionStringLocalTransaction))
            //{
            //    conn.Open();
            //    cmd.Connection = conn;
            //    cmd.CommandType = CommandType.StoredProcedure;
            //    cmd.CommandText = GetDeletesp();
            //    cmd.ExecuteNonQuery();
            //}
        }

        public void Delete<T1>(T1 Id,string userID)
        {
            SqlParameter Parm = GetParameter();
            Parm.Value = Id;
            SqlCommand cmd = new SqlCommand();
            cmd.Parameters.Add(Parm);
            ExecuteCommand(cmd, GetDeletesp());

            InsertDML(Id, userID, GetDeletesp());
        }
        #endregion

        #region 共用方法
        public T ExcuteSqlToGetEntity(string spname, params SqlParameter[] parm)
        {
            T Entity = null;
            using (SqlDataReader rdr = sqlHelper.ExecuteReader(sqlHelper.ConnectionStringLocalTransaction, CommandType.StoredProcedure, spname, parm))
            {
                if (rdr.Read())
                    Entity = GetEntityRecord(rdr);
                else
                    Entity = GetEntityRecord();
            }
            return Entity;
        }

        public IList<T> ExcuteSqlToGetEntities(string spname, params SqlParameter[] parm)
        {
            IList<T> Entities = new List<T>();
            using (SqlDataReader rdr = sqlHelper.ExecuteReader(sqlHelper.ConnectionStringLocalTransaction, CommandType.StoredProcedure, spname, parm))
            {
                while (rdr.Read())
                {
                    T Entity = GetEntityRecord(rdr);
                    Entities.Add(Entity);
                }
            }
            return Entities;
        }
        #endregion

        #region 虚拟方法由子类重写
        public virtual T GetEntityRecord(SqlDataReader rdr)
        {
            //由子类重写
            return null;
        }

        public virtual T GetEntityRecord()
        {
            //由子类重写
            return null;
        }

        public virtual string GetInsertsp()
        {
            //由子类重写
            return null;
        }

        public virtual string GetUpdatesp()
        {
            //由子类重写
            return null;
        }

        public virtual string GetDeletesp()
        {
            //由子类重写
            return null;
        }

        public virtual SqlParameter GetParameter()
        {
            //由子类重写
            return null;
        }

        public virtual SqlParameter[] GetParameters()
        {
            //由子类重写
            return null;
        }

        public virtual void SetParameters(T Entity, params SqlParameter[] Parms)
        {
            //由子类重写
        }
        #endregion

        #region 记录数据库操作
        protected void InsertDML(T Entity, string userID,string spname)
        {
            DMLActionInfo dai = new DMLActionInfo(DateTime.Now, userID, spname, BuildParams(Entity));
            DMLAction da = new DMLAction();
            da.DMLActionInsert(dai);       
        }
        protected void InsertDML<T1>(T1 Id, string userID, string spname)
        {
            DMLActionInfo dai = new DMLActionInfo(DateTime.Now, userID, spname, BuildParams(Id));
            DMLAction da = new DMLAction();
            da.DMLActionInsert(dai);
        }

        protected string BuildParams(T Entity)
        {
            SqlParameter[] Parms = GetParameters();
            SetParameters(Entity, Parms);
            StringBuilder sb = new StringBuilder();
            foreach (SqlParameter parm in Parms)
                sb.Append(parm.ParameterName + "=" + parm.Value.ToString() + " and ");
            string strparams = sb.ToString();
            if (!string.IsNullOrEmpty(strparams))
                strparams = strparams.Remove(strparams.Length - 5, 5);
            return strparams;
        }

        protected string BuildParams<T1>(T1 Id)
        {
            SqlParameter Parm = GetParameter();
            Parm.Value = Id;
            string strparams = Parm.ParameterName + "=" + Parm.Value.ToString();
            return strparams;
        }
        #endregion
    }
}
